package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.CartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.ProductSkuFeignClient;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.SkuPrice;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName CartServiceImpl
 * @Author 波
 * @Date 2024/8/10 15:48
 */
@Service
public class CartServiceImpl implements CartService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Resource
    private ProductSkuFeignClient productSkuFeignClient;


    private String getCartKey(Long userId) {
        //定义key user:userId:cart
        return "user:cart:" + userId;
    }

    /**
     * 添加商品到购物车
     *
     * @param skuId
     * @param skuNum
     */
    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        //先判断哈希中是否有该商品，如果有就改变0数量，没有就新增商品信息
        if (boundHashOperations.hasKey(skuId.toString())) {
            CartInfo cartInfo = boundHashOperations.get(skuId.toString());
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
            boundHashOperations.put(skuId.toString(), cartInfo);
        } else {
            CartInfo cartInfo = new CartInfo();
            cartInfo.setSkuNum(skuNum);
            cartInfo.setSkuId(skuId);
            cartInfo.setUserId(userId);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());
            //远程调用查询剩余数据
            R<ProductSku> productSkuResult = productSkuFeignClient.getProductSku(skuId, SecurityConstants.INNER);
            if (R.FAIL == productSkuResult.getCode()) {
                throw new ServiceException(productSkuResult.getMsg());
            }
            cartInfo.setThumbImg(productSkuResult.getData().getThumbImg());
            cartInfo.setSkuName(productSkuResult.getData().getSkuName());
            cartInfo.setCartPrice(productSkuResult.getData().getSalePrice());
            cartInfo.setSkuPrice(productSkuResult.getData().getSalePrice());
            boundHashOperations.put(skuId.toString(), cartInfo);
        }
    }

    @Override
    public List<CartInfo> cartList() {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            List<Long> skuIdList = cartInfoList.stream().map(cartInfo -> cartInfo.getSkuId()).collect(Collectors.toList());
            R<List<SkuPrice>> skuPriceListResult = productSkuFeignClient.getSkuPriceList(skuIdList, SecurityConstants.INNER);
            if (R.FAIL == skuPriceListResult.getCode()) {
                throw new ServiceException(skuPriceListResult.getMsg());
            }
            Map<Long, BigDecimal> skuIdToPriceMap = skuPriceListResult.getData().stream().collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));
            cartInfoList.forEach(cartInfo -> {
                cartInfo.setSkuPrice(skuIdToPriceMap.get(cartInfo.getSkuId()));
            });
            return cartInfoList;
        }
        return new ArrayList<CartInfo>();
    }

    /**
     * 删除购物车的商品
     *
     * @param skuId
     */
    @Override
    public void deleteCart(Long skuId) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        boundHashOperations.delete(skuId.toString());
    }

    /**
     * 修改商品选中状态
     *
     * @param skuId
     * @param isChecked
     */
    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        //先根据skuId查出购物车中的商品信息
        CartInfo cartInfo = boundHashOperations.get(skuId.toString());
        cartInfo.setIsChecked(isChecked);
        boundHashOperations.put(skuId.toString(), cartInfo);
    }

    /**
     * 全选商品
     *
     * @param isChecked
     */
    @Override
    public void allCheckCart(Integer isChecked) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        cartInfoList.forEach(cartInfo -> {
            CartInfo cartInfoNew = boundHashOperations.get(cartInfo.getSkuId().toString());
            cartInfoNew.setIsChecked(isChecked);
            boundHashOperations.put(cartInfo.getSkuId().toString(), cartInfoNew);
        });

    }

    @Override
    public void clearCart() {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        redisTemplate.delete(cartKey);
    }

    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        ArrayList<CartInfo> cartInfos = new ArrayList<>();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        //所有的商品商品项
        List<CartInfo> cartInfoList = boundHashOperations.values();
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList.forEach(cartInfo -> {
                if (cartInfo.getIsChecked().intValue() == 1) {
                    cartInfos.add(cartInfo);
                }
            });
        }
        return cartInfos;
    }

    @Override
    public Boolean updateCartCheckedPrice(Long userId) {
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        cartInfoList = cartInfoList.stream().filter(cartInfo -> cartInfo.getIsChecked() == 1).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList.forEach(cartInfo -> {
                //获取最新价格
                R<SkuPrice> skuPriceNew = productSkuFeignClient.getSkuPrice(cartInfo.getSkuId(), SecurityConstants.INNER);
                if (R.FAIL == skuPriceNew.getCode()) {
                    throw new ServiceException(skuPriceNew.getMsg());
                }
                cartInfo.setCartPrice(skuPriceNew.getData().getSalePrice());
                cartInfo.setSkuPrice(skuPriceNew.getData().getSalePrice());
                boundHashOperations.put(cartInfo.getSkuId().toString(), cartInfo);
            });

        }
        return true;
    }

    /**
     * 删除购物车选中的商品
     * @param userId
     * @return
     */
    @Override
    public Boolean deleteCheckedCartInfo(Long userId) {
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        cartInfoList=cartInfoList.stream().filter(cartInfo -> cartInfo.getIsChecked().intValue() == 1).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            for (CartInfo cartInfo : cartInfoList) {
                boundHashOperations.delete(cartInfo.getSkuId().toString());
            }
        }
        return true;
    }

}
